package service;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import serviceInterface.ScheduleServiceInterface;
import util.DateUtil;
import util.IConstant;
import domain.Driver;
import domain.Location;
import domain.Mission;
import domain.POS;
import domain.Person;
import domain.Schedule;
import domain.ScheduleStatus;

@Stateless
public class ScheduleService implements ScheduleServiceInterface{
	
	@PersistenceContext 
	private EntityManager entityManager;
	
	//For driver so it will get only prioritized or completed schedule 
	public List<Schedule> getAllScheduleForDriver(Person person){
		
		Query query = entityManager.createQuery("SELECT p FROM Person AS p WHERE p.userName=:name");
		query.setParameter("name", person.getUserName());
        Person p = (Person) query.getSingleResult();
        Driver d = (Driver) p.getRoles().get(0);
        List<Schedule> schedules = d.getSchedules();
        for(int i=0; i<schedules.size(); i++){
        	Schedule s = schedules.get(i);
        	s.sortMisionsByPriority();
        }
		return schedules;
	}
	
	//get all schedule in the past of particular driver 
	public List<Schedule> getPassedScheduleForDriver(Person person){
		
		Query query = entityManager.createQuery("SELECT p FROM Person AS p WHERE p.userName=:name");
		query.setParameter("name", person.getUserName());
        Person p = (Person) query.getSingleResult();
        Driver d = (Driver) p.getRoles().get(0);
        List<Schedule> schedules = d.getPassedSchedules();
        for(int i=0; i<schedules.size(); i++){
        	Schedule s = schedules.get(i);
        	s.sortMisionsByPriority();
        }
		return schedules;
	}
	
	//For driver so it will get only prioritized or completed schedule
	public List<Schedule> getNotPassedScheduleForDriver(Person person){
		
		Query query = entityManager.createQuery("SELECT p FROM Person AS p WHERE p.userName=:name");
		query.setParameter("name", person.getUserName());
        Person p = (Person) query.getSingleResult();
        Driver d = (Driver) p.getRoles().get(0);
        
        List<Schedule> schedules = d.getNotPassedSchedules();
        for(int i=0; i<schedules.size(); i++){
        	Schedule s = schedules.get(i);
        	s.sortMisionsByPriority();
        }
		return schedules;
	}
	
	public List<POS> getPOS(int scheduleId){
		Schedule schedule = entityManager.find(Schedule.class, scheduleId);
			List<POS> posList = schedule.getPrioritizedPOS();
		return posList;
		
	}
	
	public String updateCompleteStatus(int scheduleId, int missionId){
		Schedule schedule = entityManager.find(Schedule.class, scheduleId);
		schedule.updateCompleteMission(missionId);
		schedule.checkAndUpdateCompleteStatus();
		entityManager.flush();
		
		String message = "Updated Successfully";
		return message;
	}

	public List<Schedule> getUnPrioritizeSc() {
		List<Schedule> sc = new ArrayList<Schedule>();
		try {
			Query query = entityManager.createQuery("SELECT p FROM Schedule AS p WHERE p.status=ScheduleStatus.unpriortized");
			sc =  query.getResultList();
			
		}catch (Exception e) {
			e.printStackTrace();
		}
		return sc;
	}

	public void updateDeliveryStatus(long scheduleId, String missionIdList,long driverId) {
		System.out.println("scheduleId = "+scheduleId);
		System.out.println("missionIdList = "+missionIdList);
		System.out.println("driverId = "+driverId);
		
		Schedule schedule = entityManager.find(Schedule.class, scheduleId);
		System.out.println("sc ==> "+schedule.getId());
		Person driver = entityManager.find(Person.class, driverId);
		
		Driver dri = (Driver) driver.getRoles().get(0);
		dri.addSchedules(schedule);
		System.out.println("driver ==> "+dri.getRouteArea());
		
		schedule.setPrioritizedTime(DateUtil.getCurrentTimestamp());
		schedule.setStatus(ScheduleStatus.priortized);
		
		String[] missionId = missionIdList.split(":");
		List<Mission> missions = schedule.getMissions();
		int prioritize = 1;
		
		for(int j = 0 ;j<missionId.length - 1 ;j++){
			schedule.updatePriorityAndFromPOS(entityManager.find(POS.class, missionId[j]),entityManager.find(POS.class, missionId[j+1]),prioritize);
			prioritize ++;
		}
		
		entityManager.flush();
		
		
		
	}

	@Override
	public List<POS> getUnPrioritizePOS(int scheduleId) {
		Schedule schedule = entityManager.find(Schedule.class, scheduleId);
		List<POS> posList = new ArrayList<POS>();
		Query query = entityManager.createQuery("SELECT p FROM POS AS p WHERE p.name=:name ");
		query.setParameter("name",	IConstant.WARE_HOUSE);
		POS warehouse = (POS) query.getSingleResult();
		
		
		posList.add(warehouse);
		
		for(POS p:schedule.getUnPrioritizePOS()){
//			System.out.println("Missionnnnnnnn = "+p.getMission());
			posList.add(p);
		}
//		posList = schedule.getUnPrioritizePOS();
		return posList;
	}
	
	//prioritized and completed
	public List<Schedule> getCurrentActiveSchedule(){
		
		Query query = entityManager.createQuery("SELECT s FROM Schedule AS s WHERE s.status=ScheduleStatus.priortized or s.status=ScheduleStatus.completed ");
        
        List<Schedule> schedules = new ArrayList<Schedule>();
        schedules =  query.getResultList();
        List<Schedule> tempList = new ArrayList<Schedule>();
        for(int i=0; i<schedules.size(); i++){
        	Schedule s = schedules.get(i);
        	if(!s.isItPassedSchedule()){
        		s.sortMisionsByPriority();
        		tempList.add(s);
        	}
        }
		return tempList;
	}
	
	public List<Mission> getMission(int scheduleId){
		Schedule schedule = entityManager.find(Schedule.class, scheduleId);
		schedule.sortMisionsByPriority();
		List<Mission> missionList = schedule.getMissions();
		return missionList;
		
	}

	public Mission getMissionDetailForTransfer(long missionId) {
		Mission mission = entityManager.find(Mission.class, missionId);
		
		return mission;
	}
	
	public Location getCurrentLocation(long scheduleId){
		
		Query query = entityManager.createQuery("SELECT d FROM Driver AS d, IN( d.schedules ) s WHERE s.id = :scheduleId");
		query.setParameter("scheduleId", scheduleId);
		Driver driver = (Driver) query.getSingleResult();
		Location location = null;
		if(driver!=null)
			location = driver.getLocation();
		return location;
	}
}
